package xyz.jcat.biz.gateway.auth;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import xyz.jcat.webflux.sucurity.DefaultServerAccessDeniedHandler;
import xyz.jcat.webflux.sucurity.DefaultServerAuthenticationEntryPoint;
import xyz.jcat.webflux.sucurity.DefaultServerLogoutSuccessHandler;
import xyz.jcat.webflux.sucurity.RedisTokenReactiveAuthenticationManager;
import xyz.jcat.webflux.sucurity.UserInfoHeaderSettingWebFilter;

@EnableWebFluxSecurity
public class SecurityConfig {

    //TODO 配置
    private String[] permitPaths = {
            "/biz/member/login"
    };

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        //http header bearer token
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(new RedisTokenReactiveAuthenticationManager());
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        http
                .httpBasic().disable()
                .cors().disable()
                .csrf().disable()
                .authorizeExchange()
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                //请求白名单
                .pathMatchers(permitPaths).permitAll()
                //请求权限控制
                .anyExchange().access(new ReactiveAuthorizationManagerImpl())
                .and()
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHORIZATION)
                .addFilterAfter(new UserInfoHeaderSettingWebFilter(), SecurityWebFiltersOrder.AUTHORIZATION)
                .logout()
                //退出登录成功处理
                .logoutSuccessHandler(new DefaultServerLogoutSuccessHandler())
                .and()
                .exceptionHandling()
                //认证异常处理
                .authenticationEntryPoint(new DefaultServerAuthenticationEntryPoint())
                //权限异常处理
                .accessDeniedHandler(new DefaultServerAccessDeniedHandler())
        ;

        return http.build();
    }

}
